#version 330 core

out vec4 FragColor;  
in vec3 ourColor;
in vec2 TexCoord;           // 从顶点着色器传递的纹理坐标 范围是 [0,1]
in vec3 Normal;
in vec3 FragPos;            // 片段在世界坐标中的位置

vec3 lightColor = vec3(1.0f, 1.0f, 1.0f);  // 光源颜色

uniform vec3 lightPosFromMain;      // 光源位置
uniform vec3 viewPosFromMain;       // 摄像机位置 计算镜面反射
float specularStrength = 0.8;       // 镜面反射强度

// 分别为三个光照分量定义一个材质颜色(Material Color)
// 都是把之前的lightStrength替换为以下分量 光照分量 
// 漫反射贴图显示了箱子最基本的外观, 但是因为有一个镜面反射, 导致木制部分也有高光反射
// 所以需要一个镜面反射贴图来限制木制部分的镜面反射, 加强木箱周边铁片的镜面反射
struct Material {
    sampler2D diffuseMap;   // 漫反射贴图
    sampler2D specularMap;  // 镜面反射贴图
    vec3 ambient;           // ambient材质向量定义了 在环境光照射下 物体表面反射什么颜色
    vec3 diffuse;           // diffuse材质向量定义了 在漫反射光照下物体表面的颜色
    vec3 specular;          // specular材质向量定义了 在镜面光照下物体的颜色
    float shininess;        // Shininess 影响镜面高光的半径
};
uniform Material material; 



struct LightIntensity {
    vec3 ambient;       // 环境光照强度
    vec3 diffuse;       // 漫反射光照强度
    vec3 specular;      // 镜面反射光照强度 
};
// main.cpp 中的声明 应该和结构体变量的名字一样 小写开头
// ourShader.setVec3("lightIntensity.ambient", 0.2f, 0.2f, 0.2f);
uniform LightIntensity lightIntensity;

void main()
{
    // 环境光
    // vec3 ambient_result = lightIntensity.ambient * lightColor * material.ambient;
    // 漫反射贴图 直接取代了光的颜色
    vec3 ambient_result = lightIntensity.ambient * texture(material.diffuseMap, TexCoord).rgb;  

    // 计算漫反射光
    vec3 norm = normalize(Normal);
    // 两个坐标点相减得到 光线方向向量
    vec3 lightDir = normalize( lightPosFromMain - FragPos );
    // 法线与光线点乘, 因为光线入射角越大 漫反射强度就越低 (相当于光投影到法线上 角度越大分量越低)
    float diff = max( dot( norm, lightDir ), 0.0 );
    vec3 diffuse_result = lightIntensity.diffuse * diff *  texture( material.diffuseMap, TexCoord ).rgb ;

    // 镜面反射
    vec3 viewDir = normalize( viewPosFromMain - FragPos );
    vec3 reflectDir = reflect( -lightDir, norm );                       // 计算光线的反射方向
    float spec = pow( max( dot( viewDir, reflectDir ), 0.0 ), 32 );     // 计算反光度 32次幂 越大越亮  
    // vec3 specular_result = lightIntensity.specular * (material.specular * spec) * lightColor;                // 计算镜面光的颜色
    vec3 specular_result = lightIntensity.specular * (spec) *  texture( material.specularMap, TexCoord ).rgb ;  // 镜面反射贴图
    // vec3 specular_result = lightIntensity.specular * (spec);  
    // vec3 specular_result =  vec3( texture( material.specularMap, TexCoord ) );  // 镜面反射贴图
    



    // vec3 result = ( ambient_result + diffuse_result + specular_result ) * vec3(1.0f, 0.5f, 0.31f);
    // <!!!> 物体只是反射光中的某些分量 不是自身发光 所以不需要乘以物体颜色 且由各个光照分量决定result

    // 验证是否实现采样镜面光贴图
    // vec3 result = ( specular_result );

    vec3 result = ambient_result + diffuse_result + specular_result ;
    FragColor = vec4( result, 1.0 );
}